from bot.enterprise_wechat_gpt.knowledge_base.knowledge_search_generate import *
from bot.enterprise_wechat_gpt.util.id_distributor import distribute


class DesignSolution(LLMAgent):
    """根据知识库检索知识 生成解决方案Agent"""
    solution_template_v1 = """
    作为一个专业的、非常懂营销的信贷领域的{salesperson_role}，你需要根据用户的问题和对话记录，构建出最合适的解决方案。  
    职责范围：金融、信贷领域，拒绝解决数学、文学、历史、计算机等和金融不相关的问题。
    注意以下事项：
    1.回复的内容是接下来和用户沟通的方案，解决方案需要限定在解决方案集合中，引导操作的时候每次只给一个方案，不要一次性给出多个方案，不要无中生有；
    2.回复的内容将用于生成具体回复用户的话术，不要包含不必要的信息；
    3.回复的内容只用于下一轮和用户沟通的话术生成，也不要列出具体详细的步骤，也不用枚举各种用户问题或解决方案的情况，只需要给出最后解决方案的结论；
    4.请注意额度不够和没有额度是不同的概念，额度不够是额度>0，没有额度是额度=0。如果没有额度或额度不足500，就不要给出"将现有额度取出来"的方案了；
    5.金条提额方式最多有五种：个人所得税提额、公积金提额、支付宝账单提额、微信账单提额、金条Plus额度。但并不是所有人都能看到全部的提额方案，你可以先问用户能看到哪些提额方案，或者问能看到公积金提额吗，然后再给出对应的提额方案；如果没有公积金提额再给其他的提额方案；
    6.无论金条提额、金条借款、申请信用卡、申请企业主贷、申请借钱，都会产生征信查询记录的，消费信贷的征信都是授权后查询的，只要没有逾期是没有负面影响的。如果用户比较在意查征信，可以先问一下用户本月已经查询了多少次。如果用户已经查询两次征信，那么你需要提示用户一个月内查询征信的次数最好不要超过3次以免对个人信用有负向的影响；
    7.把开头"亲爱的用户"、"亲爱的客户"等类似的招呼语过滤掉，把结尾"如有问题，请随时联系我"、"期待你的回复"等过滤掉。
    8.应国家相关政策法规要求，金条借款不得用于购房、还房贷、理财、炒股等权益性投资。也不得用于还花呗等其他借款平台。
    9.金条借款在企微专属链接【http://3.cn/10dB-VB8k】里进行，信用卡申请在专属办理链接【http://3.cn/1-0buDWG7】进行，不要让用户在京东金融APP里进行。
    
    满足不同消费需求的信贷产品组合包含：
    1. 金条：大额现金需求，使用场景灵活，最高额度20万的现金贷产品，可按1、3、6、12个月（期）进行分期，仅对部分用户开放18和24期。
    2. 京东联名信用卡：线上线下扫码消费享免息期最长50天，额度最高可达50万，即有贷款功能又可消费使用，还有京东Plus会员权益、加油优惠、一份购、影视会员等丰富权益可选。
    
    用户当前的问题：{user_question}
    用户当前的情境：{user_situation}
    解决方案集合：{multi_knowledge}
    对话记录如下：
    ===
    {conversation_history}
    ===
    
    限制条件：控制回复的字数在250字以内。
    根据用户问题、用户情境、对话记录和解决方案集合，请一步步思考，分析原因，接下来销售员的解决方案是：
    """

    solution_template_v2 = """
    作为一个专业的、非常懂营销的信贷领域的京东金融福利推荐官，你需要根据用户的问题和对话记录，构建出最合适的解决方案。
    职责范围：金融、信贷领域，拒绝解决数学、文学、历史、计算机等和金融不相关的问题。
    注意以下事项：
    1.回复的策略是接下来和用户沟通的方案，解决方案需要限定在解决方案集合中，引导操作的时候每次只给一个方案的一个步骤，不要一次性给出多个方案或多个步骤，不要无中生有；
    2.回复的策略将用于生成具体回复用户的话术，不要包含不必要的信息，输出的结果需要简洁，回复内容只用于一次沟通，因此不要包含多条指令或多个步骤
    3.回复的策略只是一句短语，不要列出具体详细的步骤，也不用枚举各种用户问题或解决方案的情况，只需要给出最后解决方案的结论；
    4.请注意额度不够和没有额度是不同的概念，额度不够是额度>0，没有额度是额度=0。如果没有额度或额度不足500，就不要给出"将现有额度取出来"的方案了；
    5.金条提额方式最多有五种：个人所得税提额、公积金提额、支付宝账单提额、微信账单提额、金条Plus额度。但并不是所有人都能看到全部的提额方案，你可以先问用户能看到哪些提额方案，或者问能看到公积金提额吗，然后再给出对应的提额方案；如果没有公积金提额再给其他的提额方案；
    6.无论金条提额、金条借款、申请信用卡、申请企业主贷、申请借钱，都会产生征信查询记录的，消费信贷的征信都是授权后查询的，只要没有逾期是没有负面影响的。如果用户比较在意查征信，可以先问一下用户本月已经查询了多少次。如果用户已经查询两次征信，那么你需要提示用户一个月内查询征信的次数最好不要超过3次以免对个人信用有负向的影响；
    7.把开头"亲爱的用户"、"亲爱的客户"等类似的招呼语过滤掉，把结尾"如有问题，请随时联系我"、"期待你的回复"等过滤掉。
    8.应国家相关政策法规要求，金条借款不得用于购房、还房贷、理财、炒股等权益性投资。也不得用于还花呗等其他借款平台。
  
    满足不同消费需求的信贷产品组合包含：
    1. 金条：大额现金需求，使用场景灵活，最高额度20万的现金贷产品，可按1、3、6、12个月（期）进行分期，仅对部分用户开放18和24期。
    2. 京东联名信用卡：线上线下扫码消费享免息期最长50天，额度最高可达50万，即有贷款功能又可消费使用，还有京东Plus会员权益、加油优惠、一份购、影视会员等丰富权益可选。

    用户当前的问题：{user_question}
    用户当前的情境：{user_situation}
    解决方案集合：{multi_knowledge}
    对话记录如下：
    ===
    {conversation_history}
    ===

    根据用户问题、用户情境、对话记录和解决方案集合，请一步步思考，接下来销售员的下一步沟通策略是：
    """

    def __init__(self, conversation_history, multi_knowledge, user_question, user_situation):
        if distribute(local_data.user_id, 2):
            self.prompt = self.solution_template_v1
        else:
            self.prompt = self.solution_template_v2
        self.conversation_str = '\n###'.join([list(d.keys())[0] + ':' + list(d.values())[0] for d in conversation_history])

        self.multi_knowledge = multi_knowledge   # 从知识库检索的多条知识
        self.user_question = user_question   # 用户问题
        self.user_situation = user_situation   # 用户情景

        self.prompt = self.prompt.format(salesperson_role=SYSTEM, conversation_history=self.conversation_str,
                                         multi_knowledge=self.multi_knowledge, user_question=self.user_question,
                                         user_situation=self.user_situation)
        super().__init__(self.prompt)



###########################################################################################################################################################

async def get_solution(deal_conversation_history, multi_knowledge, user_question, user_situation):
    user_id = local_data.user_id
    res_design_solution = ""
    if not user_question:
        return res_design_solution
    multi_knowledge = {s.get("用户问题"): s.get('答案', '') for i, s in enumerate(multi_knowledge)}
    design_solution = DesignSolution(deal_conversation_history, multi_knowledge, user_question, user_situation)
    if distribute(user_id, r=2):
        res_design_solution = await design_solution.achat_with_azure_gpt4(agent_name='解决方案')
        logging.info(f"userId:[{user_id}] [azure-gpt-4]  解决方案 原始输出结果: {res_design_solution}")
    else:
        res_design_solution = await design_solution.achat_llm(agent_name='解决方案', model_version='wechat_financial_7b_1218')
        logging.info(f"userId:[{user_id}] [自有模型]  解决方案 原始输出结果: {res_design_solution}")
    return res_design_solution




if __name__ == '__main__':
    role1, role2 = ASSISTANT, USER
    raw_conversation_history = [{role1: '有借款需要的话，可以通过企微专属链接借款，以便后期系统复审时您有机会调整额度和利率，具体显示以页面为准。请问您这次需要解决什么财务问题呢？您目前界面还有额度哈？'},
                                {role2: '还有5000额度，我要一万'}, {role2: '额度不够用，怎么办？'}, {role2: '你能给提点么'},
                                {role1: '您的额度问题我记下了哈~小鑫现在带您查看一下提额的名额哈！'}, {role1: '您打开京东金融app，点击【金条借款】-【我的】-【我的额度】，您把截图发给我一下，帮您根据您自身的情况推荐一下提额方式哈，有通道开放吗？您看到提额任务了吗？'},
                                {role2: '好的，提额专区？'}, {role2: '我这里好像有几条'}]
    deal_conversation_history = merge_role_conversation(raw_conversation_history)
    tasks_1 = [get_user_question(deal_conversation_history), get_user_situation(deal_conversation_history)]
    loops = asyncio.get_event_loop()
    user_question, user_situation = loops.run_until_complete(asyncio.gather(*tasks_1))

    multi_knowledge = search_knowledge(user_question, user_situation)
    res_design_solution = loops.run_until_complete(get_solution(deal_conversation_history, multi_knowledge, user_question, user_situation))
    print(res_design_solution)
    question_knowledge = search_knowledge(res_design_solution)   ############TODO 根据解决方案-搜索知识库 找3条知识
    res_question_knowledge = {i+1:question_knowledge[i]['答案'] for i in range(len(question_knowledge))}
    print(res_question_knowledge)



